#lang racket


(require "../base/main.rkt")

(require "domain.rkt"
         "skin.rkt")

(provide (struct-out sinwave-skin)
         sinwave-object
         sinwave-tangent
         sinwave-normal
         sinwave-binormal
         make-sinwave-skin)


(define-struct (sinwave-skin skin)
  (ax ay az)
  #:constructor-name new-sinwave-skin)

(define (sinwave-object ax ay az)
  (λ (u v)
    (let ((x (* ax u))
          (y (* ay v)))
      (xyz
       x
       y
       (* az (sin (sqrt (+ (^2 x) (^2 y)))))))))

(define (sinwave-tangent object-proc)
  (λ (u v)
    (skin-tangent object-proc)))

(define (sinwave-normal object-proc)
  (λ (u v)
    (skin-normal object-proc)))

(define (sinwave-binormal)
  skin-binormal)

(define (make-sinwave-skin ax ay az)
  (new-sinwave-skin
   (sinwave-object ax ay az)
   (sinwave-tangent (sinwave-object ax ay az))
   (sinwave-normal (sinwave-object ax ay az))
   (sinwave-binormal)
   (make-uv-domain 'closed (- 2pi) 'closed 2pi
                   'closed (- 2pi) 'closed 2pi)
   ax
   ay
   az))